package net.csdra.adapter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.tika.io.IOUtils;

import java.io.IOException;
import java.net.URLEncoder;

/**
 * Created by add on 2017/10/10.
 */
public class EMSAdapterImpl implements EMSAdapter {

    String billNumUrl;
    String trackingUrl;
    String version;
    String authenticate;
    public EMSAdapterImpl(String billNumUrl, String trackingUrl) {
        this.billNumUrl = billNumUrl;
        this.trackingUrl = trackingUrl;
    }

    public EMSAdapterImpl(String trackingUrl,String version,String authenticate ){
        this.trackingUrl = trackingUrl;
        this.version = version;
        this.authenticate = authenticate;
    }

    public GetBillNumBySysResponse getBillNumBySys(GetBillNumBySysRequest getBillNumBySysRequest) {
        //"http://os.ems.com.cn:8081/zkweb/bigaccount/getBigAccountDataAction.do?method=getBillNumBySys&xml={xml}"
        String xml = objectToXml(getBillNumBySysRequest);
        String url = this.billNumUrl + "getBillNumBySys&xml={xml}";
        String requestUrl = url.replace("{xml}", xml);
        try {
            String response = getResponse(requestUrl);
            GetBillNumBySysResponse getBillNumBySysResponse = xmlToObject(response, GetBillNumBySysResponse.class);
            return getBillNumBySysResponse;
        } catch (IOException e) {
            throw new RuntimeException("@请求异常", e);
        }
    }

    public UpdatePrintDatasResponse updatePrintDatas(UpdatePrintDatasRequest updatePrintDatasRequest) {
        String xml = objectToXml(updatePrintDatasRequest);
        //"http://os.ems.com.cn:8081/zkweb/bigaccount/getBigAccountDataAction.do?method=updatePrintDatas&xml={xml}"
        String url = this.billNumUrl + "updatePrintDatas&xml={xml}";
        String requestUrl = url.replace("{xml}", xml);
        try {
            String response = getResponse(requestUrl);
            UpdatePrintDatasResponse updatePrintDatasResponse = xmlToObject(response, UpdatePrintDatasResponse.class);
            return updatePrintDatasResponse;
        } catch (IOException e) {
            throw new RuntimeException("@请求异常", e);
        }
    }

    @Override
    public GetTrackingInfoResponse getTrackingInfo(GetTrackingInfoRequest getTrackingInfoRequest) {
        String requestUrl = this.trackingUrl + "{mail_num}";
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String request = requestUrl.replace("{mail_num}", URLEncoder.encode(getTrackingInfoRequest.getMail_num(), "UTF-8"));
//            String version = "ems_track_cn_1.0";
//            String authenticate = "5D99306186ED7326E053D2C2020ACEDD";
            String result = getResponseVerification(request, this.version, this.authenticate);
            GetTrackingInfoResponse getTrackingInfoResponse = objectMapper.readValue(result, GetTrackingInfoResponse.class);
            return getTrackingInfoResponse;
        } catch (IOException e) {
            throw new RuntimeException("值转换出错", e);
        }
    }

    private <T> String objectToXml(T t) {
        XmlMapper xmlMapper = new XmlMapper();
        try {
            String xmlResult = xmlMapper.writeValueAsString(t);
            String result = Base64.encodeBase64String(xmlResult.getBytes());
            String XMLPrm = URLEncoder.encode(result, "UTF-8");
            return XMLPrm;
        } catch (Exception e) {
            throw new RuntimeException("对象转xml失败", e);
        }
    }

    private <T> T xmlToObject(String xml, Class<T> aClass) {
        try {
            byte[] bytes = Base64.decodeBase64(xml.getBytes());
            String newStringUtf8 = StringUtils.newStringUtf8(bytes);
            T o = new XmlMapper().readValue(newStringUtf8, aClass);
            return o;
        } catch (IOException e) {
            throw new RuntimeException("xml转对象失败", e);
        }
    }

    private String getResponse(String requestUrl) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpGet = new HttpGet(requestUrl);
            CloseableHttpResponse response = httpclient.execute(httpGet);
            try {
                HttpEntity resEntity = response.getEntity();
                String theString = IOUtils.toString(resEntity.getContent());
                return theString;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }

    private String getResponseVerification(String requestUrl, String version, String authenticate) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            HttpGet httpGet = new HttpGet(requestUrl);
            httpGet.addHeader("version", version);
            httpGet.addHeader("authenticate", authenticate);
            response = httpclient.execute(httpGet);
            HttpEntity resEntity = response.getEntity();
            String theString = IOUtils.toString(resEntity.getContent());
            response.close();
            return theString;
        } finally {
            httpclient.close();
        }
    }

}
